﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Xml.Linq;
using Android.App;
using Android.Content;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using ComApp.Model;
using ComApp;

namespace AndroidApp
{
    public class AppDeploy 
    {
        public string CurrentVer = "2015-05-05";
        private string deployFile;
        public string DeployFile
        {
            get
            {
                if (string.IsNullOrEmpty(this.deployFile))
                {
                    this.deployFile = System.IO.Path.Combine(AppPath.Instance.AppDataPath,"Deploy.xml");
                    if (!System.IO.File.Exists(this.deployFile))
                    {
                        var xml = new XElement("Deploy",
                                                new XElement("UserID", Guid.NewGuid()),
                                                new XElement("UserCode", string.Empty),
                                                new XElement("UserName", string.Empty)
                                              );
                        xml.Save(this.deployFile);
                    }
                }
                return this.deployFile;
            }
        }


        public void GetNewestVer(Action<string> action)
        {
            using (var client = new WcfSystemServiceRef.WcfSystemService())
            {
                AppUnity.Instance.LogService.Log("WebService url = " + client.Url);
                client.Url = AppUnity.Instance.ServerDeploy.WcfSystemUrl;
                client.GetAndroidAppNewestVerCompleted += (s, e) =>
                        {
                            action(e.Result);
                        };
                client.GetAndroidAppNewestVerAsync();
            }
        }

        /// <summary>
        /// 建议更新
        /// </summary>
        /// <param name="action"></param>
        public void GetOldestVer(Action<string> action)
        {
            using (var client = new WcfSystemServiceRef.WcfSystemService())
            {
                AppUnity.Instance.LogService.Log("WebService url = " + client.Url);
                client.Url = AppUnity.Instance.ServerDeploy.WcfSystemUrl;
                client.GetAndroidAppOldestVerCompleted += (s, e) =>
                    {
                        action(e.Result);
                    };
                client.GetAndroidAppOldestVerAsync();
            }
        }

        public void DownloadNewestFile(Action<long,long> downloadProgress)
        {
            using (var client = new WcfSystemServiceRef.WcfSystemService())
            {
                client.Url = AppUnity.Instance.ServerDeploy.WcfSystemUrl;
                client.GetAndroidAppNewestUrlCompleted += (s, e) =>
                    {
                        var file = e.Result;
                        AppUnity.Instance.LogService.Log("try download file = " + file);
                        if (file.ToLower().EndsWith("zip"))
                            this.DownloadZipFile(file, downloadProgress);
                        else if (file.ToLower().EndsWith(".apk"))
                            this.DownloadFile(file);
                    };
                client.GetAndroidAppNewestUrlAsync();
            }
        }


        //Android获取一个用于打开APK文件的intent
        public void Install(Activity activity, string fileName)
        {
            ThisApp.Instance.ViewManager.FirstView.RunOnUiThread(() =>
                {
                    Intent intent = new Intent(Intent.ActionView);
                    intent.AddFlags(ActivityFlags.NewTask);
                    intent.SetDataAndType(Android.Net.Uri.Parse("file://" + fileName), "application/vnd.android.package-archive");
                    activity.StartActivity(intent);
                });
        }


        private void DownloadFile(string url)
        {
            if (System.IO.File.Exists(this.NewVerFile))
                System.IO.File.Delete(this.NewVerFile);

            using (var webClient = new System.Net.WebClient())
            {
                webClient.DownloadFileCompleted += (s, e) =>
                {
                    if (e.Error != null || e.Cancelled)
                    {
                        //下载失败
                        AppUnity.Instance.LogService.Log(string.Format("从{0}下载失败!", url));
                    }
                    else
                    {
                        AppUnity.Instance.LogService.Log(string.Format("试图安装{0}!", this.NewVerFile));
                        if (System.IO.File.Exists(this.NewVerFile))
                        {
                            this.Install(ThisApp.Instance.ViewManager.FirstView, this.NewVerFile);
                        }
                    }
                };
                webClient.DownloadFileAsync(new Uri(url), this.NewVerFile);
            }
        }


        private void DownloadZipFile(string url,Action<long,long> action)
        {
            using (var webClient = new System.Net.WebClient())
            {
                long bytesReceived = 0;
                webClient.DownloadProgressChanged += (s, e) =>
                    {
                        if (e.BytesReceived > bytesReceived * 1024 * 10)
                        {
                            AppUnity.Instance.RunOnUiThread(() => action(e.BytesReceived, e.TotalBytesToReceive));
                            bytesReceived ++;
                        }
                    };

                webClient.DownloadDataCompleted += (s, e) =>
                {
                    if (e.Error != null || e.Cancelled)
                    {
                        //下载失败
                        AppUnity.Instance.LogService.Log(string.Format("从{0}下载失败!", url));
                    }
                    else
                    {
                        AppUnity.Instance.LogService.Log("开始解压缩下载的内容....");
                        using (MemoryStream stream = new MemoryStream(e.Result))
                        {
                            this.UnZip(stream, this.NewVerFile);
                        }
                        AppUnity.Instance.LogService.Log("准备安装...");
                        if (System.IO.File.Exists(this.NewVerFile))
                        {
                            this.Install(ThisApp.Instance.ViewManager.FirstView, this.NewVerFile);
                        }
                    }
                };
                webClient.DownloadDataAsync(new Uri(url));
            }
        }


        private void UnZip(Stream zipStream, string unZipFile)
        {
            if (System.IO.File.Exists(unZipFile))
                System.IO.File.Delete(unZipFile);

            using (ZipInputStream s = new ZipInputStream(zipStream))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    using (FileStream streamWriter = File.Create(unZipFile))
                    {
                        int size = 2048;
                        byte[] data = new byte[size];
                        while (true)
                        {
                            size = s.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                streamWriter.Write(data, 0, size);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }

        private string NewVerFile
        {
            get
            {
                return string.Format("{0}/{1}", AppPath.Instance.AppDataPath, "AndroidApp.apk");
            }
        }

        internal void Update(Action<long, long> downloadProgress)
        {
            this.DownloadNewestFile(downloadProgress);
        }


        private XElement deployXml;
        public XElement DeployXml
        {
            get
            {
                if (this.deployXml == null)
                    this.deployXml = XElement.Load(this.DeployFile);
                return this.deployXml;
            }
        }


        public User GetCurrentUser()
        {
            var xml = this.DeployXml;
            var userID = (Guid)xml.Element("UserID");
            var userCode = xml.Element("UserCode").Value;
            var userName = xml.Element("UserName").Value;
            var user = new User() { ID = userID, UserCode = userCode, UserName = userName};
            return user;
        }


        internal void SetCurrentUser(User user, Guid roomID)
        {
            this.currentUser = user;
            this.deployXml = new XElement("Deploy",
                                    new XElement("UserID", user.ID),
                                    new XElement("UserCode", user.UserCode),
                                    new XElement("UserName", user.UserName)
                                    );

            this.deployXml.Save(this.DeployFile);
        }

        /// <summary>
        /// UserID 始终不为空，即使未注册用户，也会产生一个ID，可视为此设备ID。
        /// 注册时，先提交此ID，再注册此用户，返回UserCode
        /// 如果用户已注册，ID不变，UserCode不为空。
        /// </summary>
        private User currentUser;
        public User CurrentUser
        {
            get
            {
                if (this.currentUser == null)
                {
                    this.currentUser = this.GetCurrentUser();
                }
                return this.currentUser;
            }
        }



     
    }
}
